#if defined( __i386__ ) || defined( __x86_64__ )

#include <stdio.h>

#include "ops_x86.h"


int setHostAsmOps( struct instance* this, int regSize ){
	
	int i;
	
	if( regSize < 0 ){
		this->ops = opsList[0];
		return opsList[0]->regSize;
	}
	
	for( i = 0; opsList[i]; i++ ){
		if( opsList[i]->regSize == regSize ){
			this->ops = opsList[i];
			return opsList[i]->regSize;
		}
	}
	
	return -1;
}


/************************************************************************************
*
*
*                                8 bit
*
*
************************************************************************************/


//math
static void add_8( struct instance* this ){
	asm volatile (
		"add   %[i2], %[i1] \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->s8), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].s8), [i2] "m"(this->regs[1].s8)
		:
	);
}

static void sub_8( struct instance* this ){
	asm volatile (
		"sub   %[i2], %[i1] \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->s8), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].s8), [i2] "m"(this->regs[1].s8)
		:
	);
}

static void mul_8( struct instance* this ){
	//AH:AL = AL * r/m8
	asm volatile (
		"mov   %[i1], %%al \n"
		"mulb  %[i2]       \n"
		"pushf             \n"
		"pop   %[o2]       \n"
		"mov   %%al, %[o1] \n"
		:[o1]"=m"(this->outReg->u8), [o2]"=m"(this->cpuFlags)
		:[i1] "m"(this->regs[0].u8), [i2] "m"(this->regs[1].u8)
		:"ax", "ah", "al"
	);
}

static void imul_8( struct instance* this ){
	//AH:AL = AL * r/m8
	asm volatile (
		"mov   %[i1], %%al \n"
		"imulb %[i2]       \n"
		"pushf             \n"
		"pop   %[o2]       \n"
		"mov   %%al, %[o1] \n"
		:[o1]"=m"(this->outReg->s8), [o2]"=m"(this->cpuFlags)
		:[i1] "m"(this->regs[0].s8), [i2] "m"(this->regs[1].s8)
		:"ax", "ah", "al"
	);
}

static void div_8( struct instance* this ){
	//AL = AX / r/m8
	//remainder of the division stored in AH
	asm volatile (
		"mov   $0,    %%ah \n"
		"mov   %[i1], %%al \n"
		"divb  %[i2]       \n"
		"pushf             \n"
		"pop   %[o2]       \n"
		"mov   %%al, %[o1] \n"
		:[o1]"=m"(this->outReg->u8), [o2]"=m"(this->cpuFlags)
		:[i1] "m"(this->regs[0].u8), [i2] "m"(this->regs[1].u8)
		:"ax", "al", "ah"
	);
}

static void idiv_8( struct instance* this ){
	
	//AL = AX / r/m8
	//remainder of the division stored in AH
	asm volatile (
		"mov   %[i1], %%al \n"
		"cbw               \n"
		"idivb %[i2]       \n"
		"pushf             \n"
		"pop   %[o2]       \n"
		"mov   %%al, %[o1] \n"
		:[o1]"=m"(this->outReg->s8), [o2]"=m"(this->cpuFlags)
		:[i1] "m"(this->regs[0].s8), [i2] "m"(this->regs[1].s8)
		:"ax", "ah", "al"
	);
}

static void neg_8( struct instance* this ){
	asm volatile (
		"neg   %[i1]        \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->s8), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].s8)
		:
	);
}

//logic
static void and_8( struct instance* this ){
	asm volatile (
		"and   %[i2], %[i1] \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u8), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u8), [i2] "m"(this->regs[1].u8)
		:
	);
}

static void not_8( struct instance* this ){
	asm volatile (
		"not   %[i1]        \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u8), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u8)
		:
	);
}

static void or_8( struct instance* this ){
	asm volatile (
		"or    %[i2], %[i1] \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u8), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u8), [i2] "m"(this->regs[1].u8)
		:
	);
}

static void xor_8( struct instance* this ){
	asm volatile (
		"xor   %[i2], %[i1] \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u8), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u8), [i2] "m"(this->regs[1].u8)
		:
	);
}

//shift
static void shl_8( struct instance* this ){
	//SHL r/m8,CL
	asm volatile (
		"mov   %[i2], %%cl  \n"
		"shl   %%cl, %[i1]  \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u8), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u8), [i2] "m"(this->regs[1].u8)
		:"cl"
	);
}

static void shr_8( struct instance* this ){
	asm volatile (
		"mov   %[i2], %%cl  \n"
		"shr   %%cl, %[i1]  \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u8), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u8), [i2] "m"(this->regs[1].u8)
		:"cl"
	);
}

static void sal_8( struct instance* this ){
	asm volatile (
		"mov   %[i2], %%cl  \n"
		"sal   %%cl, %[i1]  \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->s8), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].s8), [i2] "m"(this->regs[1].u8)
		:"cl"
	);
}

static void sar_8( struct instance* this ){
	asm volatile (
		"mov   %[i2], %%cl  \n"
		"sar   %%cl, %[i1]  \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->s8), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].s8), [i2] "m"(this->regs[1].u8)
		:"cl"
	);
}

static void rol_8( struct instance* this ){
	asm volatile (
		"mov   %[i2], %%cl  \n"
		"rol   %%cl, %[i1]  \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u8), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u8), [i2] "m"(this->regs[1].u8)
		:"cl"
	);
}

static void ror_8( struct instance* this ){
	asm volatile (
		"mov   %[i2], %%cl  \n"
		"ror   %%cl, %[i1]  \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u8), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u8), [i2] "m"(this->regs[1].u8)
		:"cl"
	);
}

//other
static void fake_bswap_8( struct instance* this ){
	printf( "Do nothing.\n" );
}


static void fake_movsx_8( struct instance* this ){
	printf( "Do nothing.\n" );
}

/************************************************************************************
*
*
*                                16 bit
*
*
************************************************************************************/


//math
static void add_16( struct instance* this ){
	asm volatile (
		"add   %[i2], %[i1] \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->s16), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].s16), [i2] "m"(this->regs[1].s16)
		:
	);
}

static void sub_16( struct instance* this ){
	asm volatile (
		"sub   %[i2], %[i1] \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->s16), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].s16), [i2] "m"(this->regs[1].s16)
		:
	);
}

static void mul_16( struct instance* this ){
	//DX:AX = AX * r/m16
	asm volatile (
		"mov   %[i1], %%ax \n"
		"mulw  %[i2]       \n"
		"pushf             \n"
		"pop   %[o2]       \n"
		"mov   %%ax, %[o1] \n"
		:[o1]"=m"(this->outReg->u16), [o2]"=m"(this->cpuFlags)
		:[i1] "m"(this->regs[0].u16), [i2] "m"(this->regs[1].u16)
		:"ax", "dx"
	);
}

static void imul_16( struct instance* this ){
	//DX:AX = AX * r/m16
	asm volatile (
		"mov   %[i1], %%ax \n"
		"imulw %[i2]       \n"
		"pushf             \n"
		"pop   %[o2]       \n"
		"mov   %%ax, %[o1] \n"
		:[o1]"=m"(this->outReg->s16), [o2]"=m"(this->cpuFlags)
		:[i1] "m"(this->regs[0].s16), [i2] "m"(this->regs[1].s16)
		:"ax", "dx"
	);
}

static void div_16( struct instance* this ){
	//AX = DX:AX / r/m16
	//remainder of the division stored in DX
	asm volatile (
		"mov   $0,    %%dx \n"
		"mov   %[i1], %%ax \n"
		"divw  %[i2]       \n"
		"pushf             \n"
		"pop   %[o2]       \n"
		"mov   %%ax, %[o1] \n"
		:[o1]"=m"(this->outReg->u16), [o2]"=m"(this->cpuFlags)
		:[i1] "m"(this->regs[0].u16), [i2] "m"(this->regs[1].u16)
		:"ax", "dx"
	);
}

static void idiv_16( struct instance* this ){
	
	//AX = DX:AX / r/m16
	//remainder of the division stored in DX
	asm volatile (
		"mov   %[i1], %%ax \n"
		"cwd               \n"
		"idivw %[i2]       \n"
		"pushf             \n"
		"pop   %[o2]       \n"
		"mov   %%ax, %[o1] \n"
		:[o1]"=m"(this->outReg->s16), [o2]"=m"(this->cpuFlags)
		:[i1] "m"(this->regs[0].s16), [i2] "m"(this->regs[1].s16)
		:"ax", "dx"
	);
}

static void neg_16( struct instance* this ){
	asm volatile (
		"neg   %[i1]        \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->s16), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].s16)
		:
	);
}

//logic
static void and_16( struct instance* this ){
	asm volatile (
		"and   %[i2], %[i1] \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u16), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u16), [i2] "m"(this->regs[1].u16)
		:
	);
}

static void not_16( struct instance* this ){
	asm volatile (
		"not   %[i1]        \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u16), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u16)
		:
	);
}

static void or_16( struct instance* this ){
	asm volatile (
		"or    %[i2], %[i1] \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u16), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u16), [i2] "m"(this->regs[1].u16)
		:
	);
}

static void xor_16( struct instance* this ){
	asm volatile (
		"xor   %[i2], %[i1] \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u16), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u16), [i2] "m"(this->regs[1].u16)
		:
	);
}

//shift
static void shl_16( struct instance* this ){
	//SHL r/m16,CL
	asm volatile (
		"mov   %[i2], %%cl  \n"
		"shl   %%cl, %[i1]  \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u16), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u16), [i2] "m"(this->regs[1].u8)
		:"cl"
	);
}

static void shr_16( struct instance* this ){
	asm volatile (
		"mov   %[i2], %%cl  \n"
		"shr   %%cl, %[i1]  \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u16), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u16), [i2] "m"(this->regs[1].u8)
		:"cl"
	);
}

static void sal_16( struct instance* this ){
	asm volatile (
		"mov   %[i2], %%cl  \n"
		"sal   %%cl, %[i1]  \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->s16), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].s16), [i2] "m"(this->regs[1].u8)
		:"cl"
	);
}

static void sar_16( struct instance* this ){
	asm volatile (
		"mov   %[i2], %%cl  \n"
		"sar   %%cl, %[i1]  \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->s16), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].s16), [i2] "m"(this->regs[1].u8)
		:"cl"
	);
}

static void rol_16( struct instance* this ){
	asm volatile (
		"mov   %[i2], %%cl  \n"
		"rol   %%cl, %[i1]  \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u16), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u16), [i2] "m"(this->regs[1].u8)
		:"cl"
	);
}

static void ror_16( struct instance* this ){
	asm volatile (
		"mov   %[i2], %%cl  \n"
		"ror   %%cl, %[i1]  \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u16), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u16), [i2] "m"(this->regs[1].u8)
		:"cl"
	);
}

//other
static void xchg_16( struct instance* this ){
	
	printf( "Using xchg instead bswap.\n" );
	asm volatile (
		"mov   %[i1], %%dx \n"
		"xchg  %%dh,  %%dl \n"
		"pushf             \n"
		"pop   %[o2]       \n"
		"mov   %%dx, %[o1] \n"
		:[o1]"=m"(this->outReg->u16), [o2]"=m"(this->cpuFlags)
		:[i1] "m"(this->regs[0].u16)
		:"dx", "dh", "dl"
	);
}

static void movsx_16( struct instance* this ){
	asm volatile (
		"movsx %[i1], %[o1] \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		:[o1]"=r"(this->outReg->s16), [o2]"=m"(this->cpuFlags)
		:[i1] "m"(this->regs[0].u8)
		:
	);
}


/************************************************************************************
*
*
*                                32 bit
*
*
************************************************************************************/


//math
static void add_32( struct instance* this ){
	asm volatile (
		"add   %[i2], %[i1] \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->s32), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].s32), [i2] "m"(this->regs[1].s32)
		:
	);
}

static void sub_32( struct instance* this ){
	asm volatile (
		"sub   %[i2], %[i1] \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->s32), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].s32), [i2] "m"(this->regs[1].s32)
		:
	);
}

static void mul_32( struct instance* this ){
	//EDX:EAX = EAX * r/m32
	asm volatile (
		"mov   %[i1], %%eax \n"
		"mull  %[i2]        \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %%eax, %[o1] \n"
		:[o1]"=m"(this->outReg->u32), [o2]"=m"(this->cpuFlags)
		:[i1] "m"(this->regs[0].u32), [i2] "m"(this->regs[1].u32)
		:"eax", "edx"
	);
}

static void imul_32( struct instance* this ){
	//EDX:EAX = EAX * r/m32
	asm volatile (
		"mov   %[i1], %%eax \n"
		"imull %[i2]        \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %%eax, %[o1] \n"
		:[o1]"=m"(this->outReg->s32), [o2]"=m"(this->cpuFlags)
		:[i1] "m"(this->regs[0].s32), [i2] "m"(this->regs[1].s32)
		:"eax", "edx"
	);
}

static void div_32( struct instance* this ){
	//EAX = EDX:EAX / r/m32
	//remainder of the division stored in EDX
	asm volatile (
		"mov   $0,    %%edx \n"
		"mov   %[i1], %%eax \n"
		"divl  %[i2]        \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %%eax, %[o1] \n"
		:[o1]"=m"(this->outReg->u32), [o2]"=m"(this->cpuFlags)
		:[i1] "m"(this->regs[0].u32), [i2] "m"(this->regs[1].u32)
		:"eax", "edx"
	);
}

static void idiv_32( struct instance* this ){
	
	//EAX = EDX:EAX / r/m32
	//remainder of the division stored in EDX
	asm volatile (
		"mov   %[i1], %%eax \n"
		"cdq                \n"
		"idivl %[i2]        \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %%eax, %[o1] \n"
		:[o1]"=m"(this->outReg->s32), [o2]"=m"(this->cpuFlags)
		:[i1] "m"(this->regs[0].s32), [i2] "m"(this->regs[1].s32)
		:"eax", "edx"
	);
}

static void neg_32( struct instance* this ){
	asm volatile (
		"neg   %[i1]        \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->s32), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].s32)
		:
	);
}

//logic
static void and_32( struct instance* this ){
	asm volatile (
		"and   %[i2], %[i1] \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u32), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u32), [i2] "m"(this->regs[1].u32)
		:
	);
}

static void not_32( struct instance* this ){
	asm volatile (
		"not   %[i1]        \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u32), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u32)
		:
	);
}

static void or_32( struct instance* this ){
	asm volatile (
		"or    %[i2], %[i1] \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u32), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u32), [i2] "m"(this->regs[1].u32)
		:
	);
}

static void xor_32( struct instance* this ){
	asm volatile (
		"xor   %[i2], %[i1] \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u32), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u32), [i2] "m"(this->regs[1].u32)
		:
	);
}

//shift
static void shl_32( struct instance* this ){
	//SHL r/m32,CL
	asm volatile (
		"mov   %[i2], %%cl  \n"
		"shl   %%cl, %[i1]  \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u32), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u32), [i2] "m"(this->regs[1].u8)
		:"cl"
	);
}

static void shr_32( struct instance* this ){
	asm volatile (
		"mov   %[i2], %%cl  \n"
		"shr   %%cl, %[i1]  \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u32), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u32), [i2] "m"(this->regs[1].u8)
		:"cl"
	);
}

static void sal_32( struct instance* this ){
	asm volatile (
		"mov   %[i2], %%cl  \n"
		"sal   %%cl, %[i1]  \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->s32), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].s32), [i2] "m"(this->regs[1].u8)
		:"cl"
	);
}

static void sar_32( struct instance* this ){
	asm volatile (
		"mov   %[i2], %%cl  \n"
		"sar   %%cl, %[i1]  \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->s32), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].s32), [i2] "m"(this->regs[1].u8)
		:"cl"
	);
}

static void rol_32( struct instance* this ){
	asm volatile (
		"mov   %[i2], %%cl  \n"
		"rol   %%cl, %[i1]  \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u32), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u32), [i2] "m"(this->regs[1].u8)
		:"cl"
	);
}

static void ror_32( struct instance* this ){
	asm volatile (
		"mov   %[i2], %%cl  \n"
		"ror   %%cl, %[i1]  \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u32), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u32), [i2] "m"(this->regs[1].u8)
		:"cl"
	);
}

//other
static void bswap_32( struct instance* this ){
	asm volatile (
		"bswap %[i1]        \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u32), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u32)
		:
	);
}

static void movsx_32( struct instance* this ){
	asm volatile (
		"movsx %[i1], %[o1] \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		:[o1]"=r"(this->outReg->s32), [o2]"=m"(this->cpuFlags)
		:[i1] "m"(this->regs[0].u16)
		:
	);
}

#if defined( __x86_64__ )

/************************************************************************************
*
*                                64 bit
*                            only for x86_64
*
*
************************************************************************************/

//math
static void add_64( struct instance* this ){
	asm volatile (
		"add   %[i2], %[i1] \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->s64), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].s64), [i2] "m"(this->regs[1].s64)
		:
	);
}

static void sub_64( struct instance* this ){
	asm volatile (
		"sub   %[i2], %[i1] \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->s64), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].s64), [i2] "m"(this->regs[1].s64)
		:
	);
}

static void mul_64( struct instance* this ){
	//EDX:EAX = EAX * r/m32
	asm volatile (
		"mov   %[i1], %%rax \n"
		"mulq  %[i2]        \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %%rax, %[o1] \n"
		:[o1]"=m"(this->outReg->u64), [o2]"=m"(this->cpuFlags)
		:[i1] "m"(this->regs[0].u64), [i2] "m"(this->regs[1].u64)
		:"rax", "rdx"
	);
}

static void imul_64( struct instance* this ){
	//EDX:EAX = EAX * r/m32
	asm volatile (
		"mov   %[i1], %%rax \n"
		"imulq %[i2]        \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %%rax, %[o1] \n"
		:[o1]"=m"(this->outReg->s64), [o2]"=m"(this->cpuFlags)
		:[i1] "m"(this->regs[0].s64), [i2] "m"(this->regs[1].s64)
		:"rax", "rdx"
	);
}

static void div_64( struct instance* this ){
	//EAX = EDX:EAX / r/m32
	//remainder of the division stored in EDX
	asm volatile (
		"mov   $0,    %%rdx \n"
		"mov   %[i1], %%rax \n"
		"divq  %[i2]        \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %%rax, %[o1] \n"
		:[o1]"=m"(this->outReg->u64), [o2]"=m"(this->cpuFlags)
		:[i1] "m"(this->regs[0].u64), [i2] "m"(this->regs[1].u64)
		:"rax", "rdx"
	);
}

static void idiv_64( struct instance* this ){
	//EAX = EDX:EAX / r/m32
	//remainder of the division stored in EDX
	asm volatile (
		"mov   %[i1], %%rax \n"
		"cqto               \n"
		"idivq %[i2]        \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %%rax, %[o1] \n"
		:[o1]"=m"(this->outReg->s64), [o2]"=m"(this->cpuFlags)
		:[i1] "m"(this->regs[0].s64), [i2] "m"(this->regs[1].s64)
		:"rax", "rdx"
	);
}

static void neg_64( struct instance* this ){
	asm volatile (
		"neg   %[i1]        \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->s64), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].s64)
		:
	);
}

//logic
static void and_64( struct instance* this ){
	asm volatile (
		"and   %[i2], %[i1] \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u64), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u64), [i2] "m"(this->regs[1].u64)
		:
	);
}

static void not_64( struct instance* this ){
	asm volatile (
		"not   %[i1]        \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u64), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u64)
		:
	);
}

static void or_64( struct instance* this ){
	asm volatile (
		"or    %[i2], %[i1] \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u64), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u64), [i2] "m"(this->regs[1].u64)
		:
	);
}

static void xor_64( struct instance* this ){
	asm volatile (
		"xor   %[i2], %[i1] \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u64), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u64), [i2] "m"(this->regs[1].u64)
		:
	);
}

//shift
static void shl_64( struct instance* this ){
	//SHL r/m64,CL
	asm volatile (
		"mov   %[i2], %%cl  \n"
		"shl   %%cl, %[i1] \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u64), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u64), [i2] "m"(this->regs[1].u8)
		:"cl"
	);
}

static void shr_64( struct instance* this ){
	asm volatile (
		"mov   %[i2], %%cl  \n"
		"shr   %%cl, %[i1]  \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u64), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u64), [i2] "m"(this->regs[1].u8)
		:"cl"
	);
}

static void sal_64( struct instance* this ){
	asm volatile (
		"mov   %[i2], %%cl  \n"
		"sal   %%cl, %[i1]  \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->s64), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].s64), [i2] "m"(this->regs[1].u8)
		:"cl"
	);
}

static void sar_64( struct instance* this ){
	asm volatile (
		"mov   %[i2], %%cl  \n"
		"sar   %%cl, %[i1]  \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->s64), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].s64), [i2] "m"(this->regs[1].u8)
		:"cl"
	);
}

static void rol_64( struct instance* this ){
	asm volatile (
		"mov   %[i2], %%cl  \n"
		"rol   %%cl, %[i1]  \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u64), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u64), [i2] "m"(this->regs[1].u8)
		:"cl"
	);
}

static void ror_64( struct instance* this ){
	asm volatile (
		"mov   %[i2], %%cl  \n"
		"ror   %%cl, %[i1]  \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u64), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u64), [i2] "m"(this->regs[1].u8)
		:"cl"
	);
}

//other
static void bswap_64( struct instance* this ){
	asm volatile (
		"bswap %[i1]        \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		"mov   %[i1], %[o1] \n"
		:[o1]"=m"(this->outReg->u64), [o2]"=m"(this->cpuFlags)
		:[i1] "r"(this->regs[0].u64)
		:
	);
}

static void movsx_64( struct instance* this ){
	asm volatile (
		"movsx %[i1], %[o1] \n"
		"pushf              \n"
		"pop   %[o2]        \n"
		:[o1]"=r"(this->outReg->s64), [o2]"=m"(this->cpuFlags)
		:[i1] "m"(this->regs[0].u32)
		:
	);
}

#endif //x86-64
#endif //main
